using System;
using System.Collections;
using System.Data;
using System.Data.SQLite;
using System.IO;
using System.Globalization;
using System.Net;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Xml;
using sharpCash.ReflectionClasses;
using sharpCash.SQLwrapper;
using sharpCash.HTTPClasses;

//All I'm going to say about this file, is that it deals with everything that I need for OFX data transmissions.
//Maybe I'll comment this better later.

namespace sharpCash.OFXClasses
{
    [AttributeUsage(AttributeTargets.All,
    AllowMultiple = true)]
    public class OFXAttribute : System.Attribute
    {
        private string ofxTag;

        public string OFXTag
        {
            get { return this.ofxTag; }
        }
        public OFXAttribute(string tag)
        {
            this.ofxTag = tag;
        }
    }
    public class baseOFX
    {
        static public Hashtable fillVarList(Type type)
        {
            Hashtable rv = new Hashtable();
            foreach (PropertyInfo propInfo in type.GetProperties())
            {
                OFXAttribute[] attr = (OFXAttribute[])propInfo.GetCustomAttributes(typeof(OFXAttribute), false);
                if (attr != null && attr.Length > 0)
                {
                    rv.Add(attr[0].OFXTag, propInfo.Name);
                }
            }
            return rv;
        }
        static public object fillObjectFromXML(Type objType, XmlReader reader, Hashtable varList)
        {
            string endingName;
            object rv = objType.GetConstructor(System.Type.EmptyTypes).Invoke(null);
            reader.Read();
            endingName = reader.Name;
            reader.Read(); // pass STMTTRN
            while (reader.Name != endingName || reader.NodeType != XmlNodeType.EndElement)
            {
                string elementName = reader.Name;
                object varName = varList[elementName];
                if (varName != null)
                {
                    PropertyInfo propInfo = objType.GetProperty(varName.ToString());
                    if (propInfo != null)
                    {
                        if (propInfo.PropertyType.Namespace == "sharpCash" && propInfo.PropertyType.IsClass)
                        {
                            propInfo.SetValue(rv, baseOFX.fillObjectFromXML(propInfo.PropertyType, reader.ReadSubtree(), baseOFX.fillVarList(propInfo.PropertyType)), null);
                        }
                        else
                        {
                            string elementValue;
                            reader.Read();//Value
                            elementValue = reader.Value;
                            if (propInfo.PropertyType.IsEnum)
                            {
                                propInfo.SetValue(rv, ObjectStringClass.StringToStyle(elementValue, propInfo.PropertyType, propInfo.GetValue(rv, null)), null);
                            }
                            else
                            {
                                propInfo.SetValue(rv, elementValue, null);
                            }
                            reader.Read();// end element
                        }
                    }
                }
                reader.Read(); // start element

            }

            return rv;
        }
    }
    public class OFXREQUEST
    {
        private string username;
        private string password;
        private BaseSQL mySQL;

        public OFXREQUEST()
        {
            mySQL = new BaseSQL(Alfray.SharpFlow.Utils.SharpFlowToOfxUtils.settingFileName("OFXDB.db"));
            mySQL.makeTableIfExist(new FIDATA());
        }
        public void setUserPassword(string user, string pass)
        {
            this.username = user;
            this.password = pass;
        }
        public DataSet getOrganizations(string letter)
        {
            return mySQL.returnAll(new FIDATA(), "FIDATA_Name LIKE '" + letter + "%'");
        }
        public object getOrganizations(string column, string value)
        {
            FIDATA rv = new FIDATA();
            mySQL.returnOneObject(rv, column + "='" + value + "'", null, null);
            return rv;
        }
        public void updateSQLDB()
        {
            string response;
            Hashtable varList = baseOFX.fillVarList(typeof(FIDATA));
            for (int i = 1; i < 4; i++)
            {
                response = HTTPClass.HttpGet("http://moneycentral.msn.com/money/2006/mnynet/service/ols/filist.aspx?SKU=3&VER=6&T=" + i.ToString() + "&S=*&R=1&O=0&TEST=0", null, null, null);
                if (response != "")
                {
                    byte[] buffer = Encoding.ASCII.GetBytes(response);
                    MemoryStream myStream = new MemoryStream(buffer);
                    XmlTextReader reader = new XmlTextReader(myStream);
                    reader.WhitespaceHandling = WhitespaceHandling.Significant;
                    reader.Read(); // Header
                    reader.Read(); // FIL
                    mySQL.beginTransaction(new FIDATA());
                    int j = 0;
                    while (reader.Name != "")
                    {
                        reader.ReadToFollowing("fi");
                        if (reader.Name != "")
                        {
                            this.updateMasterList(reader.ReadSubtree(), varList);
                        }
                        j++;
                        if (reader.Name == "")
                            reader.Read();
                    }
                    mySQL.endTransaction(new FIDATA());
                }
                else
                {
                    throw new Exception("Cant access server to update list");
                }
            }
        }
        public FIDATA getFIDATA(string guid)
        {
            return this.getFIDATA(guid, true);
        }
        public FIDATA getFIDATA(string guid, bool searchOnline)
        {
            FIDATA myFIDATA = new FIDATA();
            if (!searchOnline)
                mySQL.returnOneObject(myFIDATA, "FIDATA_GUID='" + guid + "'", null, null);
            else
            {
                DataSet ds = mySQL.returnAll(myFIDATA, "FIDATA_GUID='" + guid + "'");
                if (ds.Tables[0].Rows.Count > 0)
                {
                    string resp = "";
                    resp = HTTPClass.HttpGet("http://moneycentral.msn.com/money/2006/mnynet/service/olsvcupd/OnlSvcBrandInfo.aspx?MSNGUID=&GUID=" + guid + "&SKU=3&VER=6", null, null, null);
                    if (resp != "")
                    {
                        //resp = resp.Replace("\0", "");
                        byte[] buffer = Encoding.ASCII.GetBytes(resp);
                        MemoryStream myStream = new MemoryStream(buffer);
                        XmlTextReader newreader = new XmlTextReader(myStream);
                        newreader.WhitespaceHandling = WhitespaceHandling.Significant;
                        newreader.ReadToFollowing("ProviderSettings");
                        myFIDATA = (FIDATA)baseOFX.fillObjectFromXML(typeof(FIDATA), newreader.ReadSubtree(), baseOFX.fillVarList(typeof(FIDATA)));
                        mySQL.addDataToDB(myFIDATA, ds.Tables[0].Rows[0]["ID"]);
                    }
                    else
                    {
                        throw new Exception("Can not access server to get data");
                    }
                }
            }
            return myFIDATA;
        }
        private void updateMasterList(XmlReader myreader, Hashtable varList)
        {
            string guid = "";
            string name = "";
            myreader.ReadToFollowing("name");
            myreader.Read();
            name = myreader.Value;
            myreader.ReadToFollowing("guid");
            myreader.Read();
            guid = myreader.Value;
            FIDATA myFIDATA = new FIDATA();
            myFIDATA.GUID = guid;
            myFIDATA.Name = name;
            DataSet ds = mySQL.returnAll(myFIDATA, "FIDATA_GUID='" + guid + "'");
            if (ds.Tables[0].Rows.Count > 0)
                mySQL.addDataToDB(myFIDATA, ds.Tables[0].Rows[0]["ID"]);
            else
                mySQL.addDataToDB(myFIDATA);
        }
        public object[] getStatementFromOFX(FIDATA myFIDATA, OFXSTMTREQ stmtRQ, Type transType)
        {
            OFX writer = new OFX();
            object[] rv = new object[] { null };
            string appid = "Money";
            string appver = "1500";
            string requestString = writer.returnHeader();
            NetworkCredential credentials = new NetworkCredential(stmtRQ.UserName, stmtRQ.PassWord);
            CookieContainer cookies = new CookieContainer();
            requestString += "\n\n";
            requestString += writer.startElement("OFX");
            requestString += writer.startElement("SIGNONMSGSRQV1");
            requestString += writer.startElement("SONRQ");
            requestString += writer.writeField("DTCLIENT", DateTime.Now.ToString("yyyyMMddHHmmss"));
            requestString += writer.writeField("USERID", stmtRQ.UserName);
            requestString += writer.writeField("USERPASS", stmtRQ.PassWord);
            requestString += writer.writeField("LANGUAGE", "ENG");
            requestString += writer.startElement("FI");
            requestString += writer.writeField("ORG", myFIDATA.FIORG);
            requestString += writer.writeField("FID", myFIDATA.FID);
            requestString += writer.endElement(); // end FI
            requestString += writer.writeField("APPID", appid);
            requestString += writer.writeField("APPVER", appver);
            //            requestString += writer.writeField("CLIENTUID","22576921-8E39-4A82-9E3E-EDDB121ADDEE");
            requestString += writer.endElement();  // END SONRQ
            requestString += writer.endElement();  // END SIGNONMSGSRQV1
            requestString += "\n";
            if (stmtRQ.AcctType == AccountType.CC)
            {
                requestString += writer.startElement("CREDITCARDMSGSRQV1");
                requestString += writer.startElement("CCSTMTTRNRQ");
            }
            else
            {
                requestString += writer.startElement("BANKMSGSRQV1");
                requestString += writer.startElement("STMTTRNRQ");

            }
            requestString += "<TRNUID>" + Guid.NewGuid().ToString("N");
            if (stmtRQ.AcctType == AccountType.CC)
            {
                requestString += writer.startElement("CCSTMTRQ");
                requestString += writer.startElement("CCACCTFROM");
            }
            else
            {
                requestString += writer.startElement("STMTRQ");
                requestString += writer.startElement("BANKACCTFROM");
                requestString += writer.writeField("BANKID", stmtRQ.BankID);
            }
            requestString += writer.writeField("ACCTID", stmtRQ.AcctID);
            if (stmtRQ.AcctType == AccountType.BANK)
                requestString += writer.writeField("ACCTTYPE", stmtRQ.BankAcctType.ToString());
            requestString += writer.endElement();//ACCTFROM
            requestString += writer.startElement("INCTRAN");
            requestString += writer.writeField("DTSTART", stmtRQ.DTstart);
            requestString += writer.writeField("INCLUDE", "Y");
            requestString += writer.endElement();//INCTRAN
            requestString += writer.endElement();//STMTRQ
            requestString += writer.endElement();//STMTTRNRQ
            requestString += writer.endElement();//MSGSRQV1
            requestString += writer.endElement();//OFX
            string response = "";
            try
            {
                response = HTTPClass.HttpPost(myFIDATA.URI, requestString, credentials, cookies, true);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "....Before submitting to bug report, do a full OFX server update");
            }
            if (response != "")
            {
                OFXParser myParser = new OFXParser(response);
                rv = myParser.parseOFXdata(transType);
            }
            return rv;
        }
    }
    public class OFXParser
    {
        private bool xmlVersion = false;
        private string oldUID = "NONE";
        private string newUID = "";
        private string XMLdata;
        public OFXParser(string data)
        {
            if (data.IndexOf("OFXHEADER:100") != -1)
            {
                xmlVersion = false;
            }
            else
            {
                xmlVersion = true;
            }
            this.XMLdata = data;
        }
        public object[] parseOFXdata(Type returnType)
        {
            object[] rv;
            if (!xmlVersion)
            {
                rv = this.parseVersion1(returnType);
            }
            else rv = this.parseVersion2(this.XMLdata, returnType);
            return rv;
        }
        private object[] parseVersion1(Type returnType)
        {
            string[] lines = this.passV1Header(this.XMLdata);
            string converted = this.convertToXML(String.Join("", lines));
            return this.parseVersion2(converted, returnType);
        }
        private object[] parseVersion2(string data, Type type)
        {
            byte[] buffer = Encoding.ASCII.GetBytes(data);
            MemoryStream myStream = new MemoryStream(buffer);
            XmlTextReader reader = new XmlTextReader(myStream);
            Hashtable varibleList = baseOFX.fillVarList(type);
            ArrayList rv = new ArrayList();
            if (xmlVersion)
            {
                reader.Read(); //xmlHeader
                reader.Read(); //ofx Header
            }
            /* Verify the signon message */
            reader.Read(); // OFX OPEN
            if (reader.Name == "OFX")
            {
                string statementName = "";
                reader.Read(); // Signonmsgwrapper
                reader.Read(); // SONRS
                reader.Read(); // status
                reader.Read(); // code
                reader.Read(); // code value
                if (reader.Value != "0")
                    throw new Exception("Sign-on was not ok.  Code: " + reader.Value.ToString());
                while (reader.Name != "SIGNONMSGSRSV1")
                {
                    reader.Read();
                }
                reader.Read();  //end of Signonmsgwrapper
                statementName = reader.Name;
                while (reader.Name != "")
                {
                    reader.ReadToFollowing("STMTTRN");
                    if (reader.Name != "")
                    {
                        object tmp = baseOFX.fillObjectFromXML(type, reader.ReadSubtree(), varibleList);
                        rv.Add(tmp);
                    }
                }
                return rv.ToArray();
            }
            else
                return null;
        }
        private string convertToXML(string sgml)
        {
            int start = 0;
            int end = 0;
            while (start < sgml.Length && start != -1)
            {
                string tag = "";
                start = sgml.IndexOf("<", end);
                if (start != -1)
                {
                    end = sgml.IndexOf(">", start);
                    if (end != -1)
                    {
                        tag = sgml.Substring(start + 1, end - start - 1);
                        if (!tag.StartsWith("/"))
                        {
                            if (sgml.IndexOf("</" + tag + ">", end) == -1)
                            {
                                start = sgml.IndexOf("<", end);
                                sgml = sgml.Insert(start, "</" + tag + ">");
                            }
                        }
                    }
                    else start = -1;
                }
            }
            return sgml;
        }
        private string[] passV1Header(string text)
        {
            string[] lines = text.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
            string[] rv = new string[lines.Length + 1];
            int i = 0;
            if (lines[i++] == "OFXHEADER:100")
            {
                if (lines[i++] == "DATA:OFXSGML")
                {
                    if (lines[i++] == "VERSION:102")
                    {
                        if (lines[i++] == "SECURITY:NONE")
                        {
                            if (lines[i++] == "ENCODING:USASCII")
                            {
                                if (lines[i++] == "CHARSET:1252")
                                {
                                    if (lines[i++] == "COMPRESSION:NONE")
                                    {
                                        if (lines[i++] == "OLDFILEUID:" + oldUID)
                                        {
                                            newUID = lines[i++].Split(':')[1];
                                            Array.Copy(lines, i, rv, 0, lines.Length - i);
                                        }
                                        else throw new Exception("OLDFILEUID does not match");
                                    }
                                    else throw new Exception("I dont handle Compression");
                                }
                                else throw new Exception("I dont handle any charset other than 1252");
                            }
                            else throw new Exception("I dont handle any encoding other than USASCII");
                        }
                        else throw new Exception("I dont handle OFX security protocol");
                    }
                    else throw new Exception("I only handle version 102");
                }
                else throw new Exception("The data must be of type OFXSGML");
            }
            else throw new Exception("Header is wrong");
            return rv;
        }
    }
    public class OFX
    {
        private Stack elementStack = new Stack();
        private int prevID = 0;
        int newID = 0;
        public int genUID()
        {
            Random rnd = new Random();
            return rnd.Next();
        }
        public string startElement(string name)
        {
            elementStack.Push(name);
            return String.Format("<{0}>", name);
        }
        public string endElement()
        {
            return String.Format("</{0}>", elementStack.Pop().ToString());
        }
        public string returnHeader()
        {
            prevID = newID;
            newID = genUID();
            return
                /*
                "\n<!--XML declaration-->\n<?xml version=\"1.0\"?>\n\n<!--OFX declaration-->\n<?OFX OFXHEADER=\"200\" VERSION=\"211\" SECURITY=\"NONE\" OLDFILEUID=\"NONE\" NEWFILEUID=\"NONE\"?>"+
                "\n\n<!--OFX request-->";
                /*"<?OFX OFXHEADER=\"200\" VERSION=\"211\" SECURITY=\"NONE\" OLDFILEUID=\"NONE\" NEWFILEUID=\"NONE\"?>";*/
                String.Join("\n", new String[] {"OFXHEADER:100",
                           "DATA:OFXSGML",
                           "VERSION:102",
                           "SECURITY:NONE",
                           "ENCODING:USASCII",
                           "CHARSET:1252",
                           "COMPRESSION:NONE",
                           "OLDFILEUID:NONE",
                           "NEWFILEUID:" + genUID().ToString(),});
        }
        public string writeField(string fieldName, string value)
        {
            return String.Format("<{0}>{1}", fieldName, value);
        }
        public OFX()
        {
        }
    }
    [OFXAttribute("PAYEE")]
    public class OFXPAYEE
    {
        protected string name;
        protected string address1;
        protected string address2;
        protected string address3;
        protected string city;
        protected string state;
        protected string postalCode;
        protected string country;
        protected string phone;
        protected bool isPayeeField = false;

        [ColumnAttribute(true, "Payee Name", true, typeof(string))]
        [OFXAttribute("NAME")]
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        [ColumnAttribute(false, "Payee address1", true, typeof(string))]
        [OFXAttribute("ADDR1")]
        public string Address1
        {
            get { return isPayeeField ? address1 : ""; }
            set { address1 = isPayeeField ? value : ""; }
        }
        [ColumnAttribute(false, "Payee address2", true, typeof(string))]
        [OFXAttribute("ADDR2")]
        public string Address2
        {
            get { return isPayeeField ? address2 : ""; }
            set { address2 = isPayeeField ? value : ""; }
        }
        [ColumnAttribute(false, "Payee address3", true, typeof(string))]
        [OFXAttribute("ADDR3")]
        public string Address3
        {
            get { return isPayeeField ? address3 : ""; }
            set { address3 = isPayeeField ? value : ""; }
        }
        [ColumnAttribute(false, "Payee city", true, typeof(string))]
        [OFXAttribute("CITY")]
        public string City
        {
            get { return isPayeeField ? city : ""; }
            set { city = isPayeeField ? value : ""; }
        }
        [ColumnAttribute(false, "Payee state", true, typeof(string))]
        [OFXAttribute("STATE")]
        public string State
        {
            get { return isPayeeField ? state : ""; }
            set { state = isPayeeField ? value : ""; }
        }
        [ColumnAttribute(false, "Payee zip code", true, typeof(int))]
        [OFXAttribute("POSTALCODE")]
        public string ZipCode
        {
            get { return postalCode; }
            set { postalCode = value; }
        }
        [ColumnAttribute(false, "Payee country", true, typeof(string))]
        [OFXAttribute("COUNTRY")]
        public string Country
        {
            get { return isPayeeField ? country : ""; }
            set { country = isPayeeField ? value : ""; }
        }
        [ColumnAttribute(false, "Payee phone #", true, typeof(string))]
        [OFXAttribute("PHONE")]
        public string Phone
        {
            get { return isPayeeField ? phone : ""; }
            set { phone = isPayeeField ? value : ""; }
        }
        [ColumnAttribute(false, "", false)]
        public bool IsPayeeField
        {
            get { return isPayeeField; }
            set { isPayeeField = value; }
        }
    }
    public class OFXACCOUNTINFO
    {
        protected AccountType type = AccountType.NA;
        protected string bankID;
        protected string accountID;
        protected BankAccountType bankType = BankAccountType.NA;
        protected string branchID;
        protected string acctKey;
        protected bool isInternational = false;

        [ColumnAttribute(true, "Account Type", true, typeof(AccountType))]
        public AccountType Type
        {
            get { return type; }
            set { type = value; }
        }
        [ColumnAttribute(false, "Routing Number", true, typeof(string))]
        [OFXAttribute("BANKID")]
        public string BankID
        {
            get { return type == AccountType.BANK ? bankID : ""; }
            set { bankID = type == AccountType.BANK ? value : ""; }
        }
        [ColumnAttribute(false, "Branch ID International", true, typeof(string))]
        [OFXAttribute("BRANCHID")]
        public string BranchID
        {
            get { return type == AccountType.BANK ? branchID : ""; }
            set { branchID = type == AccountType.BANK ? value : ""; }
        }
        [ColumnAttribute(true, "Bank Account Type", true, typeof(BankAccountType))]
        [OFXAttribute("ACCTTYPE")]
        public BankAccountType BankType
        {
            get { return type == AccountType.BANK ? bankType : BankAccountType.NA; }
            set { bankType = type == AccountType.BANK ? value : BankAccountType.NA; }
        }
        [ColumnAttribute(false, "Account Number", true, typeof(string))]
        [OFXAttribute("ACCTID")]
        public string AccountID
        {
            get { return accountID; }
            set { accountID = value; }
        }
        [ColumnAttribute(false, "International Account Key", true, typeof(string))]
        [OFXAttribute("ACCTKEY")]
        public string AcctKey
        {
            get { return isInternational ? acctKey : ""; }
            set { acctKey = isInternational ? value : ""; }
        }
    }
    [OFXAttribute("STMTTRN")]
    public class OFXSTMTTRN
    {
        protected TransactionType type = TransactionType.OTHER;
        protected string postedDate;
        protected string userInitDate;
        protected string fundAvailDate;
        protected string amount;
        protected string transID;
        protected string serverID;
        protected string checkNumber;
        protected string referanceNumber;
        protected string _SIC;
        protected string payeeID;
        protected OFXPAYEE payeeInfo;
        protected string memo;
        protected string accountInfoID;
        protected string currency;

        [ColumnAttribute(false, "Transaction Type", true, typeof(TransactionType))]
        [OFXAttribute("TRNTYPE")]
        public TransactionType Type
        {
            get { return type; }
            set { type = value; }
        }
        [ColumnAttribute(true, "Date Posted", true, typeof(DateTime))]
        [OFXAttribute("DTPOSTED")]
        public string PostedDate
        {
            get { return postedDate; }
            set
            {
                DateTime dt = DateTime.MinValue;
                if (value != null)
                {
                    string date = value.Split(new char[] { '.' })[0];
                    string tryParse = "yyyyMMddHHmmss";
                    //YYYYMMDDHHMMSS
                    if (date.Length > tryParse.Length)
                        date = date.Remove(tryParse.Length, date.Length - tryParse.Length);
                    if (DateTime.TryParseExact(date, tryParse, null, System.Globalization.DateTimeStyles.AllowWhiteSpaces, out dt))
                    {
                        postedDate = dt.ToString("d", DateTimeFormatInfo.InvariantInfo);
                    }
                    else if (DateTime.TryParse(value, out dt))
                    {
                        postedDate = dt.ToString("d", DateTimeFormatInfo.InvariantInfo);
                    }
                    else postedDate = value;
                }
                else postedDate = value;
            }
        }
        [ColumnAttribute(true, "Date User Initiated", true, typeof(DateTime))]
        [OFXAttribute("DTUSER")]
        public string UserInitDate
        {
            get { return userInitDate; }
            set
            {
                DateTime dt = DateTime.MinValue;
                if (value != null)
                {
                    string date = value.Split(new char[] { '.' })[0];
                    string tryParse = "yyyyMMddHHmmss";
                    //YYYYMMDDHHMMSS
                    if (date.Length > tryParse.Length)
                        date = date.Remove(tryParse.Length, date.Length - tryParse.Length);
                    if (DateTime.TryParseExact(date, tryParse, null, System.Globalization.DateTimeStyles.AllowWhiteSpaces, out dt))
                    {
                        userInitDate = dt.ToString("d", DateTimeFormatInfo.InvariantInfo);
                    }
                    else if (DateTime.TryParse(value, out dt))
                    {
                        userInitDate = dt.ToString("d", DateTimeFormatInfo.InvariantInfo);
                    }
                    else userInitDate = value;
                }
                else userInitDate = value;
            }
        }
        [ColumnAttribute(false, "Date Funds Available", true, typeof(DateTime))]
        [OFXAttribute("DTAVAIL")]
        public string FundAvailDate
        {
            get { return fundAvailDate; }
            set
            {
                DateTime dt = DateTime.MinValue;
                if (value != null)
                {
                    string date = value.Split(new char[] { '.' })[0];
                    string tryParse = "yyyyMMddHHmmss";
                    //YYYYMMDDHHMMSS
                    if (date.Length > tryParse.Length)
                        date = date.Remove(tryParse.Length, date.Length - tryParse.Length);
                    if (DateTime.TryParseExact(date, tryParse, null, System.Globalization.DateTimeStyles.AllowWhiteSpaces, out dt))
                    {
                        fundAvailDate = dt.ToString("d", DateTimeFormatInfo.InvariantInfo);
                    }
                    else if (DateTime.TryParse(value, out dt))
                    {
                        fundAvailDate = dt.ToString("d", DateTimeFormatInfo.InvariantInfo);
                    }
                    else fundAvailDate = value;
                }
                else fundAvailDate = value;
            }
        }
        [ColumnAttribute(true, "Amount", true, typeof(decimal))]
        [OFXAttribute("TRNAMT")]
        public string Amount
        {
            get { return amount; }
            set { amount = value; }
        }
        [ColumnAttribute(false, "TransID", false, typeof(string))]
        [OFXAttribute("FITID")]
        public string TransID
        {
            get { return transID; }
            set { transID = value; }
        }
        [ColumnAttribute(false, "ServerID", false, typeof(string))]
        [OFXAttribute("SRVRTID")]
        public string ServerID
        {
            get { return serverID; }
            set { serverID = value; }
        }
        [ColumnAttribute(true, "Check Number", true, typeof(int))]
        [OFXAttribute("CHECKNUM")]
        public string CheckNumber
        {
            get { return checkNumber; }
            set { checkNumber = value; }
        }
        [ColumnAttribute(false, "Referance Number", true, typeof(string))]
        [OFXAttribute("REFNUM")]
        public string ReferanceNumber
        {
            get { return referanceNumber; }
            set { referanceNumber = value; }
        }
        [ColumnAttribute(false, "Standard Industrial Code", true, typeof(int))]
        [OFXAttribute("SIC")]
        public string SIC
        {
            get { return _SIC; }
            set { _SIC = value; }
        }
        [ColumnAttribute(false, "Payee ID", false, typeof(string))]
        [OFXAttribute("PAYEEID")]
        public string PayeeID
        {
            get { return payeeID; }
            set { payeeID = value; }
        }
        [ColumnAttribute(false, "", false, typeof(string))]
        [OFXAttribute("PAYEE")]
        public OFXPAYEE PayeeInfo
        {
            get { return payeeInfo; }
            set { payeeInfo = value; }
        }
        [ColumnAttribute(false, "", false, typeof(string))]
        [OFXAttribute("NAME")]
        public string Name
        {
            get
            {
                if (payeeInfo != null)
                    return payeeInfo.Name;
                else return null;
            }
            set
            {
                if (payeeInfo == null)
                    payeeInfo = new OFXPAYEE();
                payeeInfo.Name = value;
            }
        }
        [ColumnAttribute(false, "Memo", true, typeof(string))]
        [OFXAttribute("MEMO")]
        public string Memo
        {
            get { return memo; }
            set { memo = value; }
        }
        [ColumnAttribute(false, "", false, typeof(string))]
        public string AccountInfoID
        {
            get { return accountInfoID; }
            set { accountInfoID = value; }
        }
        [ColumnAttribute(false, "Currency", true, typeof(string))]
        [OFXAttribute("CURRENCY")]
        public string Currency
        {
            get { return currency; }
            set { currency = value; }
        }
    }
    public class OFXRQ
    {
        private string username;
        private string password;
        public string UserName
        {
            get { return username; }
            set { username = value; }
        }
        public string PassWord
        {
            get { return password; }
            set { password = value; }
        }
    }
    public class OFXSTMTREQ : OFXRQ
    {
        private string acctID;
        private string dtstart;
        private AccountType acctType = AccountType.NA;
        private string bankID;
        private BankAccountType bankAcctType = BankAccountType.NA;

        public string AcctID
        {
            get { return acctID; }
            set { acctID = value; }
        }
        public string DTstart
        {
            get { return dtstart; }
            set { dtstart = value; }
        }
        public AccountType AcctType
        {
            get { return this.acctType; }
            set { this.acctType = value; }
        }
        public string BankID
        {
            get { return bankID; }
            set { this.bankID = value; }
        }
        public BankAccountType BankAcctType
        {
            get { return this.bankAcctType; }
            set { this.bankAcctType = value; }
        }
    }
    public class FIDATA
    {
        private string name;
        private string guid;
        private string org;
        private string fid;
        private string uri;
        [OFXAttribute("Name")]
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        [OFXAttribute("FIPID")]
        public string GUID
        {
            get { return guid; }
            set { guid = value; }
        }
        [OFXAttribute("Org")]
        public string FIORG
        {
            get { return org; }
            set { org = value; }
        }
        [OFXAttribute("FID")]
        public string FID
        {
            get { return fid; }
            set { fid = value; }
        }
        [OFXAttribute("ProviderURL")]
        public string URI
        {
            get { return uri; }
            set { uri = value; }
        }
    }
}
